package Or

import (
	"errors"
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"strconv"
	"strings"
)

type TableSum struct{}

/*
Rows oracle 查询表的统计信息中行数
*/
func (or TableSum) Rows(s global.TableSumInput) (rowsCount global.RowsReturnResult, err error) {
	var (
		event = "[oracleRows]"
		f1    any
	)
	for _, v := range []string{
		//"USER_TABLES",
		"all_tables",
		"dba_tables",
	} {
		rowsCount.BaseResult.Sql = fmt.Sprintf("select num_rows as \"tableRows\" from %v where owner='%s' and table_name='%s'", v, s.TableInfo.Schema, s.TableInfo.BackendTableName)
		//收集统计信息
		if rowsCount.BaseResult.TimeOut, f1, err = ExecSelectSql(ExecSqlInputS{
			Ss:           s,
			Event:        event,
			SelectSqlStr: rowsCount.BaseResult.Sql,
			Expect:       ETL.String,
		}); err != nil || f1 == nil {
			if err != nil {
				err = errors.New(fmt.Sprintf("%v %v", event, err))
			}
			continue
		}
		if strings.EqualFold(fmt.Sprintf("%v", f1), "<null>") {
			f1 = "0"
		}
		if rowsCount.Result, err = strconv.ParseUint(fmt.Sprintf("%v", f1), 10, 64); err == nil {
			break
		} else {
			err = errors.New(fmt.Sprintf("%v table sum conversion int failed. process:{sql:%v,shard:%v,db:%v,result:%v,err:%v}", event, rowsCount.BaseResult.Sql, "single", s.Db, f1, err))
		}
	}
	if s.TableInfo.RowsLimit > 0 {
		rowsCount.Result = uint64(s.TableInfo.RowsLimit)
	}
	return
}

func (or TableSum) Count(s global.TableSumInput) (rowsCount global.CountReturnResult, err error) {
	var (
		event = "[oracleCount]"
		f1    any
	)
	//收集统计信息
	rowsCount.BaseResult.Sql = fmt.Sprintf("select \n"+
		"/*+ parallel(5) */ count(1) as \"tableRows\" \n"+
		"from %v %v T \n"+
		"where 1=1 \n"+
		"%v %v %v",
		tableObject(s.TableInfo.Schema, s.TableInfo.BackendTableName, s.TableInfo.PartitionName),
		specifyScn(s.Input.Scn),
		rowsLimitC(s.TableInfo.RowsLimit),
		whereSqlFilter(s.SqlFilter.WhereSql),
		//whereAddFilter(s.SqlFilter.WhereAdd),
		"",
	)
	//收集统计信息
	if rowsCount.BaseResult.TimeOut, f1, err = ExecSelectSql(ExecSqlInputS{
		Ss:           s,
		Event:        event,
		SelectSqlStr: rowsCount.BaseResult.Sql,
		Expect:       ETL.Map,
	}); err != nil || f1 == nil {
		if err != nil {
			err = errors.New(fmt.Sprintf("%v %v", event, err))
		}
		return
	}
	if rowsCount.Result, err = strconv.ParseUint(fmt.Sprintf("%v", f1.(map[string]any)["tableRows"]), 10, 64); err != nil {
		err = errors.New(fmt.Sprintf("%v table sum conversion int failed. process:{sql:%v,shard:%v,db:%v,result:%v,err:%v}", event, rowsCount.BaseResult.Sql, "single", s.Db, f1, err))
		return
	}
	return
}
func (or TableSum) CountDirect(s global.TableSumInput) (bool, int64) {
	return true, int64(len(s.PartitionNameGarth))
}
